package com.huawei.cloud.phone.management.adapter.connection;

import com.huawei.cloud.phone.management.adapter.user.LoginChecker;
import com.huawei.cloud.phone.management.adapter.utils.HttpUtils;
import com.huawei.cloud.phone.management.application.connection.ConnectionService;
import com.huawei.cloud.phone.management.application.connection.dto.ConnectionDTO;
import com.huawei.cloud.phone.management.application.connection.dto.EventInfoDTO;
import com.huawei.cloud.phone.management.application.connection.dto.RequestDTO;
import com.huawei.cloud.phone.management.common.exception.AuthFailedException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.Objects;
import java.util.Optional;

@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/connection")
public class ConnectionController {
    private final ConnectionService connectionService;

    @LoginChecker
    @PostMapping(value = "/allocate")
    public ConnectionDTO allocateConnection(@Valid @RequestBody ConnectionDTO connectionDTO) {
        log.info("get connection by user phone id {}, clientType: {}", connectionDTO.getUserPhoneId(), connectionDTO.getClientType());
        Optional<String> userId = HttpUtils.getUserId();
        if (!userId.isPresent()) {
            throw new AuthFailedException();
        }
        return connectionService.getConnection(userId.get(), connectionDTO.getUserPhoneId(),
                ConnectionDTO.ClientType.getClientType(connectionDTO.getClientType()));
    }

    /**
     * 云手机事件上报，包含接入上报、退出上报
     *
     * @param eventInfoDTO 上报事件
     * @return 事件处理结果
     */
    @PostMapping(value = "event")
    public RequestDTO reportEvent(@Valid @RequestBody EventInfoDTO eventInfoDTO) {
        log.info("report event, phone id: {}, status: {}", eventInfoDTO.getEvent().getPhoneId(), eventInfoDTO.getEvent().getStatus());
        connectionService.reportEvent(eventInfoDTO);
        return new RequestDTO();
    }

    /**
     * 云手机心跳上报
     *
     * @param eventInfoDTO 心跳事件
     * @return 事件处理结果
     */
    @PostMapping(value = "heartbeat")
    public RequestDTO heartbeat(@Valid @RequestBody EventInfoDTO eventInfoDTO) {
        long startTime = System.currentTimeMillis();
        log.debug("heartbeat, phone: {}, connected: {}", eventInfoDTO.getEvent().getPhoneId(), Objects.nonNull(eventInfoDTO.getEvent().getSessionId()));
        connectionService.heartbeat(eventInfoDTO);
        long cost = System.currentTimeMillis() - startTime;
        if (cost > 300) {
            log.warn("heartbeat cost {}", cost);
        }
        return new RequestDTO();
    }
}
